<?php
namespace App\Services;

use App\Enum\ActivityEnum;
use App\Http\Controllers\AesController;
use App\Models\User;
use App\Models\VerificationCode;
use Carbon\Carbon;
use EasyWeChat\Kernel\Exceptions\DecryptException;
use Overtrue\LaravelWeChat\Facade;

/**
 * 乘客端登录相关
 * Class PassengerLoginService
 * @package App\Services
 */
class PassengerLoginService extends BaseService
{


    /**
     * 账号登录
     * @param $username 用户名 （先仅支持手机号验证）
     * @param $password 密码
     */
    public function accountLogin(string $username, string $password)
    {
        $username_field = 'phone';
        $user           = User::query()->firstWhere($username_field, $username);

        if ( !$user )
            return_bob('该账号尚未注册，请先注册', 0, 200);

        if ( !password_verify($password, $user->password) )
            return_bob('密码不正确,请重新输入', 0, 200);

        if ( $user->status ==2 )
            return_bob('该账号已被禁止登录', 0, 200);

        return $this->respondWithToken($user);
    }


    /**
     * 微信小程序登录
     * @param string $code
     * @param string $iv
     * @param string $encryptedData
     * @throws \App\Exceptions\BobException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    public function wxminLogin(string $code, string $iv, string $encryptedData)
    {
        try {

            $app = Facade::miniProgram();
            $session = $app->auth->session($code);
            //['session_key'=> 'Yg4PiZoBWX/XGnW/xZKkxg==' ,'openid'=> 'oWLg4457OgqSURzGEBS_YxFRS5BM']
            if(isset($session['errcode']))
                return_bob($session['errmsg'], 0, 200);

            $decryptedData = $app->encryptor->decryptData($session['session_key'], $iv, $encryptedData);
            //['phoneNumber'=> 15388449057, 'purePhoneNumber'=>15388449057, 'countryCode'=> 86， 'watermark'=> ['timestamp'=> 1589534859, 'appid'=>'wx9a50d308dd263315']]
            if(!isset($decryptedData['purePhoneNumber']) || !$decryptedData['purePhoneNumber'])
                return_bob('登录失败，缺少手机号码', 0, 200);

            $user = User::query()->firstWhere('phone', $decryptedData['purePhoneNumber']);
            if ( !$user ) {//不存在则添加
                $user = $this->registerByPhone($decryptedData['purePhoneNumber'], $session['openid']);
                if($user === false) {
                    return_bob('登录失败', 0, 200);
                }
            }
            return $this->respondWithToken($user);
        }catch (DecryptException $exception) {
            return_bob($exception->getMessage(), 0, 200);
        }
    }


    public function phoneLogin(string $phone, string $code)
    {
        $code_info = VerificationCode::query()->where('channel', 'sms')->where('account', $phone)->orderByDesc('created_at')->first();
        if(!$code_info || $code_info->state == 1 || $code_info->code != $code) {
            return_bob('验证码有误', 0, 200);
        }
        $code_info->state = 1;
        $code_info->save();
        $user = User::query()->firstWhere('phone', $phone);
        if ( !$user ) {//不存在则添加
            $user = $this->registerByPhone($phone);
            if($user === false) {
                return_bob('登录失败', 0, 200);
            }
        }
        return $this->respondWithToken($user);
    }


    /**
     * 根据手机号码注册
     * @param string $phone
     * @param string $openid
     * @return User|bool
     */
    public function  registerByPhone(string $phone, string $openid = '')
    {
        $user_model = new User();

        $user_model->phone = $phone;
        $user_model->open_id = $openid;
        $user_model->company_id = 1;
        $user_model->status = 3;
        $user_model->source = '1';
        $user_model->sex = '3';
        $user_model->balance = 0;

        if( !$user_model->save() )
            return false;

        return $user_model;
    }


    /**
     * Get the token array structure.
     *
     * @param string $token
     *
     * @param $user
     * @return array
     * @author Bob(bobcoder@qq.com)
     */
    public function respondWithToken(User $user): array
    {
        // 直接创建token并设置有效期
        $createToken = $user->createToken($user->password);
        $createToken->token->expires_at = Carbon::now()->addDays(30);
        $createToken->token->save();

        //创建swoole token
        $swoole_token = AesController::encrypt($user->id);
        $user->token = $swoole_token;
        $user->save();

        //发放优惠券
        if(!PassengerActivityService::checkGrantActivityCoupon($user->id, ActivityEnum::ActivityRegisterId))
            PassengerActivityService::grantActivityCoupon($user->id, ActivityEnum::ActivityRegisterId);

        return [
            'token' => $createToken->accessToken,
            'token_type' => 'Bearer',
            'user' => [
                'id' => $user->id,
                'nick_name' => $user->nick_name,
                'phone' => $user->phone,
                'avatar' => $user->avatar,
                'wxmini_auth' => $user->open_id?1:0,
                'status' => $user->status,
                'swoole_token' => $swoole_token,
            ],
            'expires_in' => Carbon::now()->addDays(30)
        ];
    }
}
